<?php

namespace app\qsapi\service;


use app\admin\model\game\BoxPcGameSource;
use app\qsapi\model\BoxGame;
use app\qsapi\model\BoxGameCate;
use app\qsapi\model\BoxMemberGamePlay;
use app\qsapi\model\BoxMemberGameLookLog;
use app\qsapi\model\BoxMemberGamePlayLog;
use app\qsapi\model\BoxMemberGameLook;
use app\qsapi\model\game\BoxPcGameEngine;
use think\Collection;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

class MyGameService extends BaseService
{


    /**
     * 我玩过的游戏列表
     * @param $member_id
     * @param $param
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function playedList($member_id, $param): array
    {
        if(empty($member_id)){
            return message('接口所需参数未接受到！',false);
        }

        $platform = strtolower($this->platform) ?? '';
        $list = (new BoxMemberGamePlay)->alias("p")->leftJoin('box_game g', 'p.game_id=g.id');

        //PC端游戏更新添加版本控制
        // if($platform == 'pc'){
        //     $list = $list->leftJoin('cq_box_pc_game_source a', 'a.package_id = g.pc_package_id')
        //         ->field('a.version game_version,a.file_url pc_game_download_url');
        // }

        $list = $list->field("g.id,p.game_id,g.game_name,g.icon,g.is_hot,g.content,g.status,g.open_type,g.android_package_name,g.android_download_url,g.ios_download_url,g.android_bag,g.ios_bag,g.ios_app_store_id,g.ios_bag_type,g.cate_id,g.is_transfer,g.is_yun,g.yun_hang_up_bag,g.pc_game_file_name,g.pc_game_project_name,g.pc_engine_key,g.pc_package_id,g.pc_open_type");

        // 判断平台
        $device = $this->device[$platform] ?? '';
        if(!empty($device)){
            $list = $list->where(['p.member_id' => $member_id, 'p.mark' => 1,'device' => $device]);
            $list = $list->where(function ($query) use($platform) {
                $query->where(Db::raw("FIND_IN_SET('0',g.on_platform)"));
                if (isset($this->device[$platform])) {
                    $device = $this->device[$platform];
                    $query->whereOr(Db::raw("FIND_IN_SET('{$device}',g.on_platform)"));
                }
            });
        }else{
            $list = $list->where(['p.member_id' => $member_id, 'p.mark' => 1]);
        }

        $list = $list->whereIn("g.status", [1])
            ->order('p.last_open_time', 'desc')
            ->paginate($param['limit'] ?? 10);
        $data['list']=[];
        $data['total']=0;
        if( $list->total()<=0)  return api_message($data);
        $list =$list->toArray();

        $gameCateModel = new  BoxGameCate();
        $whereCate[]   = ['status', '=', 1];
        $whereCate[]   = ['mark', '=', 1];
        $cate_list     = $gameCateModel->where($whereCate)->field('id,name,sort')->order('sort desc')->select();
        $cate_list     = array_column($cate_list ? $cate_list->toArray() : [], null, 'id');
        $gameEngineList = BoxPcGameEngine::where(['mark'=>1,'status'=>1])->select();
        $gameSourceList = BoxPcGameSource::where(['mark'=>1])->select();
        $gameEngineList     = array_column($gameEngineList ? $gameEngineList->toArray() : [], null, 'engine_key');
        $gameSourceList     = array_column($gameSourceList ? $gameSourceList->toArray() : [], null, 'package_id');

        $data['list'] = $list['data'];
        foreach ($data['list'] as $key => &$val) {
            if(empty($val['game_name'])){
                unset($data['list'][$key]);
                $list['total'] = $list['total'] - 1;
                continue;
            }
            if (!empty($val['android_bag'])){
                $val['android_bag'] = explode("/", $val['android_bag']);
            }
            $val['phone_transfer_flag'] = false;
            $gameService = new GameService();
            $phoneFlag = $gameService->phoneTransferFlag($val['game_id']);
            if ($phoneFlag) $val['phone_transfer_flag'] = true;
            $labels = [];
            if ($val['cate_id']) {
                $cate_ids = explode(",", $val['cate_id']);
                foreach ($cate_ids as $i => $v) {
                    if (isset($cate_list[$v])) {
                        $labels[$i] = $cate_list[$v]['name'];
                    }
                }
            }
            $val['cate_name'] = array_values($labels);
            // $res = Db::table('cq_box_game_cate')
            //     ->where('id', 'in', $val['cate_id'])
            //     ->field('name')->select();
            // $data['list'][$key]['cate_name'] = array_column($res, 'name');
            // unset($data['list'][$key]['cate_id']);

            if($platform == 'pc'){
                if($val['pc_open_type'] == 0){
                    $val['game_version']           = $gameEngineList[$val['pc_engine_key']]['version'] ?? '';
                    $val['pc_game_download_url']   = $gameEngineList[$val['pc_engine_key']]['engine_download_url'] ?? '';
                    $val['file_name']              = $gameEngineList[$val['pc_engine_key']]['file_name'] ?? '';
                    $val['file_size']              = $gameEngineList[$val['pc_engine_key']]['file_size'] ?? '';
                    $val['decompression_size']     = $gameEngineList[$val['pc_engine_key']]['decompression_size'] ?? '';
                }elseif ($val['pc_open_type'] == 1){
                    $val['game_version']           = $gameSourceList[$val['pc_package_id']]['version'] ?? '';
                    $val['pc_game_download_url']   = $gameSourceList[$val['pc_package_id']]['file_url'] ?? '';
                    $val['file_name']              = $gameSourceList[$val['pc_package_id']]['file_name'] ?? '';
                    $val['file_size']              = $gameSourceList[$val['pc_package_id']]['file_size'] ?? '';
                    $val['decompression_size']     = $gameSourceList[$val['pc_package_id']]['decompression_size'] ?? '';
                }
            }
        }
        $data['total'] = $list['total'];
        return api_message($data);

    }


    /**
     * 我看过的列表
     * @param $member_id
     * @param $param
     * @return BoxGame[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function seenList($member_id, $param): array
    {
        if(empty($member_id)){
            return message('接口所需参数未接受到！',false);
        }
        $list = (new BoxMemberGameLook)->alias("l")
            ->leftJoin('box_game g', 'l.game_id=g.id')
            ->field("g.id,l.game_id,g.game_name,g.icon,g.is_hot,g.content,g.status,g.open_type,g.android_package_name,g.android_download_url,g.ios_download_url,g.android_bag,g.ios_bag,g.ios_app_store_id,g.ios_bag_type,g.cate_id,g.is_transfer,is_yun,yun_hang_up_bag")
            ->where(['l.member_id' => $member_id]);

        $platform = strtolower($this->platform) ?? '';
        // 判断平台
        if(isset($this->device[$platform])){
            $list = $list->where(function ($query) use($platform) {
                $query->where(Db::raw("FIND_IN_SET('0',g.on_platform)"));
                if (isset($this->device[$platform])) {
                    $device = $this->device[$platform];
                    $query->whereOr(Db::raw("FIND_IN_SET('{$device}',g.on_platform)"));
                }
            });
        }

        $list = $list->whereIn("g.status", [1,3])
            ->order('l.last_look_time', 'desc')
            ->paginate($param['limit'] ?? 10);

        $data['list']=[];
        $data['total']=0;
        if ($list->total() <= 0) {
            return api_message($data, '你还没有玩过游戏，快去找个游戏体验一下吧！');
        }
        $data['list'] = $list->toArray()['data'];
        foreach ($data['list'] as $key => &$val) {
            if(empty($val['game_name'])){
                unset($data['list'][$key]);
                $list['total'] = $list->total() - 1;
                continue;
            }
            if (!empty($val['android_bag'])){
                $val['android_bag'] = explode("/", $val['android_bag']);
            }
            $val['phone_transfer_flag'] = false;
            $gameService = new GameService();
            $phoneFlag = $gameService->phoneTransferFlag($val['game_id']);
            if ($phoneFlag){
                $val['phone_transfer_flag'] = true;
            }
            $res = Db::table('cq_box_game_cate')->where('id', 'in', $val['cate_id'])->field('name')->select();
            $data['list'][$key]['cate_name'] = array_column($res, 'name');
            unset($data['list'][$key]['cate_id']);
        }
        $data['total'] = $list->total();
        return api_message($data);
    }


    /**
     * 启动游戏,埋点接口
     * $member_id  用户ID
     * $user_id  小号ID
     * $game_id  游戏ID
     * @param $member_id
     * @param $user_id
     * @param $game_id
     * @param bool $isApi
     * @return array|void
     */
    public function startGame($member_id, $user_id, $game_id, bool $isApi=true)
    {
        $platform = strtolower($this->platform) ?? '';
        if(!empty($platform)) $platform = $this->device[$platform];
        if(empty($member_id) || empty($game_id)  ||  !$user_id){
            return api_message('接口所需参数未接受到！',false);
        }
        Db::startTrans();
        try {
            //添加启动日志
            $gameStart = new BoxMemberGamePlayLog();
            $res = $gameStart->insert([
                'member_id' => $member_id,
                'game_id' => $game_id,
                'trumpet_id'=>$user_id,
                'ip' => get_client_ip(),
            ]);
            if (empty($res)) {
                throw new Exception('添加启动日志失败！');
            }

            //在玩游戏日志
            $gamePlay = new BoxMemberGamePlay();
            $map[] = ['member_id', '=', $member_id];
            $map[] = ['game_id', '=', $game_id];
            if(!empty($platform)) $map[] = ['device', '=', $platform];
            $info = $gamePlay->where($map)->find();
            if (empty($info)) {
                $data = [
                    'member_id' => $member_id,
                    'game_id' => $game_id,
                    'ip' => get_client_ip(),
                    'start_cnt' => 1,
                    'device' => $platform ?? ''
                ];
                $result = $gamePlay->insert($data);
            } else {
                $info->start_cnt = ['inc', 1];
                $info->mark = 1;
                $result = $info->save();
            }

            if (empty($result)) {
                throw new Exception('添加启动日志失败！');
            }
            Db::commit();
            if(!$isApi){
                return;
            }
            return api_message([], '启动游戏埋点数据保存成功', 200);
        } catch (Exception $e) {
            Db::rollback();
            if(!$isApi){
                return;
            }
            return api_message([], $e->getMessage(), 0);
        }

    }

    /**
     * 进入专区,埋点接口
     * @return array
     */
    public function seenInfo($member_id, $params)
    {
        if(empty($member_id) || empty($params['game_id'])){
            return api_message([],'接口所需参数未接受到！',0);
        }
        Db::startTrans();
        try {
            //添加启动日志
            $gameStart = new BoxMemberGameLookLog();
            $res = $gameStart->insert([
                'member_id' => $member_id,
                'game_id' => $params['game_id'],
                'ip' => get_client_ip(),
                'create_time' => date('Y-m-d H:i:s')
            ]);
            if (empty($res)) {
                throw new Exception('添加专区浏览记录失败！');
            }

            //在玩游戏日志
            $gamePlay = new BoxMemberGameLook();
            $map[] = ['member_id', '=', $member_id];
            $map[] = ['game_id', '=', $params['game_id']];
            $info = $gamePlay->where($map)->find();
            if (empty($info)) {
                $data = [
                    'member_id' => $member_id,
                    'game_id' => $params['game_id'],
                ];
                $result = $gamePlay->insert($data);
            } else {
                $info->look_cnt = ['inc', 1];
                $result = $info->save();
            }

            if (empty($result)) {
                throw new Exception('添加查看游戏埋点数据保存失败！');
            }
            Db::commit();
            return api_message([], '添加查看游戏埋点数据保存成功', 200);
        } catch (Exception $e) {
            Db::rollback();
            return api_message([], $e->getMessage(), 0);
        }
        return api_message($data);
    }


    /**
     * 卸载游戏
     * @param $member_id
     * @param $params
     * @return array
     */
    public function unloadGame($member_id, $params): array
    {
        $platform = strtolower($this->platform) ?? '';
        $platform = $this->device[$platform] ?? '';
        if(empty($member_id) || empty($params['game_id'])){
            return api_message([],'接口所需参数未接受到！',0);
        }

        $gamePlay = new BoxMemberGamePlay();
        $map[] = ['member_id', '=', $member_id];
        $map[] = ['game_id', '=', $params['game_id']];
        if(!empty($platform)) $map[] = ['device', '=', $platform];
        $info = $gamePlay->where($map)->find();
        if (!empty($info)) {
            $info->mark = 0;
            $info->save();
        }
        return api_message([], '游戏卸载成功', 200);
    }

    /**
     * Desc : getPackageId
     * User : Steven
     * Date : 2024-08-06 15:00
     * @param $member_id
     * @param $params
     * @return array
     */
    public function getPackageId($member_id, $params): array
    {
        $game_id = $params['game_id'] ?? 0;
        if(empty($game_id)){
            return api_message([],'游戏ID未接受到！',0);
        }
        $game = new BoxGame();
        $info = $game->where('id',$game_id)->field('pc_param')->find();
        $pc_params = json_decode($info['pc_param'],true);
        if(empty($pc_params)){
            return api_message([],'游戏信息未找到！',0);
        }
        $result = [];

        $replace['member_id'] = "{$member_id}";//主号
        //获取引擎版本号
        foreach ($pc_params as $item) {
            if (!$item['item'] || !$item['value']) continue;
            if (isEnclosedByBrackets($item['value']) === true) {
                //todo  动态增加盒子参数   使用占位符 {member_id}=>主账号id   {user_id}=>子账号ID  {token}=>用户token 强盛  QsSdkMainUserId  QsSdkToken  QsSdkChildUserId
                $value                             = trim($item['value'], '{}');
                $result[trim($item['item'])] = $replace[$value] ?? '';
            } else {
                $result[trim($item['item'])] = $item['value'];
            }
        }
        /*
        foreach ($pc_params as $value){
            // if($value['item'] == 'packageIdQsSdk'){
            //     $result['pc_package_id'] = $value['value'] ?? '';
            // }
            $item = trim($value['item']) ?? '';
            $val = trim($value['value']) ?? '';
            if(empty($item)) continue;
            switch ($item){
                case 'packageIdQsSdk':
                    $result['pc_package_id'] = $val;
                    break;
                case 'appId':
                    $result['appId'] = $val;
                    break;
                case 'appSecret':
                    $result['appSecret'] = $val;
                    break;
                case 'appEngine':
                    $result['appEngine'] = $val;
                    break;
                case 'PackageName':
                    $result['PackageName'] = $val;
                    break;
            }
        }
        */
        if(!empty($result['packageIdQsSdk'])){
            $appSize = BoxPcGameSource::field('file_size,decompression_size')->where('package_id','=',$result['packageIdQsSdk'])->find();
            $fileSize = $appSize['file_size'] ?? '0MB';
            $decompressionSize = $appSize['decompression_size'] ?? '0MB';
            $fileSize = explode('MB',$fileSize);
            $fileSize = $fileSize[0] ?? 0;
            $decompressionSize = explode('MB',$decompressionSize);
            $decompressionSize = $decompressionSize[0] ?? 0;
            $fileSize = str_replace(',', '', $fileSize);
            $decompressionSize = str_replace(',', '', $decompressionSize);
            $appSize =  intval(($fileSize + $decompressionSize) * 1024 * 1024) ?? 0;

        }else{
            $appSize = 0;
        }
        $result['appSize'] = $appSize ?? 0;
        if(empty($info)){
            return api_message([],'游戏信息未找到！',0);
        }
        return api_message($result,'游戏包ID获取成功');
    }

}
